from django.db import models
from django.contrib.auth.models import User
from public.models import CommonInfo
from appinput.models import App
from envx.models import Env

IS_INC_TOT_CHOICES = (
    ('TOT', r'全量部署'),
    ('INC', r'增量部署'),
)

DEPLOY_TYPE_CHOICES = (
    ('deployall', r'发布所有'),
    ('deploypkg', r'发布程序'),
    ('deploycfg', r'发布配置'),
    ('rollback', r'回滚'),
)


class DeployStatus(CommonInfo):
    # 新建、编译、待发布、发布中、失败、成功
    memo = models.CharField(max_length=1024, blank=True, verbose_name="备注")


class DeployPool(CommonInfo):
    # 这个名称要有唯一性，我们定义规则是：将但钱日期精确到秒，再加上随机数来保证唯一性。这样用户一眼就知道是按个日期的发布单。
    name = models.CharField(max_length=100, blank=True, null=True, verbose_name="发布单编号")
    description = models.CharField(max_length=1024, blank=True, verbose_name="描述")
    app_name = models.ForeignKey(App, related_name='deploy_app', on_delete=models.CASCADE, verbose_name="APP 应用")
    # 表示发布单自创建以来一共被发布了多少次。主要用来追踪用户发布的实时日志读取及历史日志读取
    deploy_no = models.IntegerField(blank=True, null=True, default=0)
    # 本次发布单所对应的GIT版本，每次编译然间时，这个信息会和App里的GIT信息组合，形成唯一定位的GIT版本，Jenkins就会根据这个信息编译。
    branch_build = models.CharField(max_length=255, blank=True, null=True)
    # 记录jenkins的编译次数，如果再编译过程中有任何问题，都可以快速定位到相关网页进行排错
    jenkins_number = models.CharField(max_length=255, blank=True, null=True)
    # 在Jenkins从Git拉取代码的过程中，会有一个唯一的Git内部区别版本号，通过这个版本号，就可以定位Git上唯一的代码版本。
    code_number = models.CharField(max_length=255, blank=True, null=True)
    # 用于记录本次是全量还是增量发布
    is_inc_tot = models.CharField(max_length=255, choices=IS_INC_TOT_CHOICES, blank=True, null=True,
                                  verbose_name="全量或增量部署")
    # 用于记录本次发布的是配置、程序包，还是项目的所有文件
    deploy_type = models.CharField(max_length=255, choices=DEPLOY_TYPE_CHOICES, blank=True, null=True,
                                   verbose_name="发布程序或配置")
    is_build = models.BooleanField(default=False, verbose_name="软件是否编译成功")
    # 用来记录创建发布单的用户
    create_user = models.ForeignKey(User, related_name='deploy_create_user', on_delete=models.CASCADE,
                                    verbose_name="创建用户")
    # 用于记录本次发布单生成的软件位于Nginx的哪个目录下。
    nginx_url = models.URLField(default=None, blank=True, null=True, verbose_name="Tengine URL")
    # 用于记录发布单处于哪个环境。注意，在杠创建发布单和进行软件编译的时候，还没有环境，所以这个字段要允许为空
    env_name = models.ForeignKey(Env, blank=True, null=True, related_name='deploy_env_name', on_delete=models.CASCADE,
                                 verbose_name="环境")
    # 用于记录发布单当前处理哪一个生命周期，当他处在创建和编译时，是独立存在的周期，一旦它环境流转之后，就可以和环境env_name组合，
    # 形成诸如“TEST 待发布”“DEV 发布异常”“PRD 发布完成”“TEST 发布中”等状态，给操作者一个清洗的提示
    deploy_status = models.ForeignKey(DeployStatus, related_name='deploy_poll_status', blank=True, null=True,
                                      on_delete=models.CASCADE, verbose_name="发布单状态")


class History(CommonInfo):
    user = models.ForeignKey(User, blank=True, null=True, related_name='history_user', on_delete=models.CASCADE,
                             verbose_name='用户')
    app_name = models.ForeignKey(App, blank=True, null=True, related_name='history_app', on_delete=models.CASCADE,
                                 verbose_name="App 应用")
    env_name = models.ForeignKey(Env, blank=True, null=True, related_name='history_env_name', on_delete=models.CASCADE,
                                 verbose_name="环境")
    deploy_name = models.ForeignKey(DeployPool, blank=True, null=True, related_name="history_deploy",
                                    on_delete=models.CASCADE, verbose_name="发布单")
    # 操作类型，包括三种：XCHANGE在进行环境刘占，deploy是在进行软件发布，operate是在进行服务器的启停
    do_type = models.CharField(max_length=32, blank=True, null=True, verbose_name="操作类型")
    # 记录差异性字段
    content = models.CharField(max_length=1024, blank=True, null=True, verbose_name="操作内容")
